package com.wechat.service.impl;

//import com.sun.deploy.association.utility.AppConstants;
import com.wechat.entity.config.AppConfig;
import com.wechat.entity.constants.Constants;
import com.wechat.entity.enums.AppUpdateFileTypeEnum;
import com.wechat.entity.enums.AppUpdateSatusEnum;
import com.wechat.entity.enums.PageSize;
import com.wechat.entity.enums.ResponseCodeEnum;
import com.wechat.entity.po.AppUpdate;
import com.wechat.entity.po.UserInfo;
import com.wechat.entity.query.AppUpdateQuery;
import com.wechat.entity.query.SimplePage;
import com.wechat.entity.vo.PaginationResultVO;
import com.wechat.exception.BusinessException;
import com.wechat.mappers.AppUpdateMapper;
import com.wechat.service.AppUpdateService;
import com.wechat.service.UserInfoService;
import com.wechat.utils.StringTools;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;


/**
 * app发布 业务接口实现
 */
@Service("appUpdateService")
public class AppUpdateServiceImpl implements AppUpdateService {


    @Resource
    private AppConfig appConfig;

    @Resource
    private AppUpdateMapper<AppUpdate, AppUpdateQuery> appUpdateMapper;

    @Resource
    private UserInfoService userInfoService;
    /**
     * 根据条件查询列表
     */
    @Override
    public List<AppUpdate> findListByParam(AppUpdateQuery param) {
        return this.appUpdateMapper.selectList(param);
    }

    /**
     * 根据条件查询列表
     */
    @Override
    public Integer findCountByParam(AppUpdateQuery param) {
        return this.appUpdateMapper.selectCount(param);
    }

    /**
     * 分页查询方法
     */
    @Override
    public PaginationResultVO<AppUpdate> findListByPage(AppUpdateQuery param) {
        int count = this.findCountByParam(param);
        int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

        SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
        param.setSimplePage(page);
        List<AppUpdate> list = this.findListByParam(param);
        PaginationResultVO<AppUpdate> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
        return result;
    }

    /**
     * 新增
     */
    @Override
    public Integer add(AppUpdate bean) {
        return this.appUpdateMapper.insert(bean);
    }

    /**
     * 批量新增
     */
    @Override
    public Integer addBatch(List<AppUpdate> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.appUpdateMapper.insertBatch(listBean);
    }

    /**
     * 批量新增或者修改
     */
    @Override
    public Integer addOrUpdateBatch(List<AppUpdate> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.appUpdateMapper.insertOrUpdateBatch(listBean);
    }

    /**
     * 多条件更新
     */
    @Override
    public Integer updateByParam(AppUpdate bean, AppUpdateQuery param) {
        StringTools.checkParam(param);
        return this.appUpdateMapper.updateByParam(bean, param);
    }

    /**
     * 多条件删除
     */
    @Override
    public Integer deleteByParam(AppUpdateQuery param) {
        StringTools.checkParam(param);
        return this.appUpdateMapper.deleteByParam(param);
    }

    /**
     * 根据Id获取对象
     */
    @Override
    public AppUpdate getAppUpdateById(Integer id) {
        return this.appUpdateMapper.selectById(id);
    }

    /**
     * 根据Id修改
     */
    @Override
    public Integer updateAppUpdateById(AppUpdate bean, Integer id) {
        return this.appUpdateMapper.updateById(bean, id);
    }

    /**
     * 根据VersionId删除---已发布的版本不允许删除
     */
    @Override
    public Integer deleteAppUpdateById(Integer id) {
        AppUpdate dbInfo = this.getAppUpdateById(id);
        if (!AppUpdateSatusEnum.INIT.getStatus().equals(dbInfo.getStatus())) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        return this.appUpdateMapper.deleteById(id);
    }

    /**
     * 保存（新建+修改）版本信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUpdate(AppUpdate appUpdate, MultipartFile file) throws IOException {
        AppUpdateFileTypeEnum fileTypeEnum = AppUpdateFileTypeEnum.getByType(appUpdate.getFileType());
        if(fileTypeEnum == null){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        //已发布的版本不可以进行修改
        if(appUpdate.getId() != null){
            AppUpdate updateInfo = getAppUpdateById(appUpdate.getId());
            if(!updateInfo.getStatus().equals(AppUpdateSatusEnum.INIT.getStatus())){
                throw new BusinessException(ResponseCodeEnum.CODE_601);
            }
        }

        //最新的版本号需要大于上一个版本号
        AppUpdateQuery appUpdateQuery = new AppUpdateQuery();
        appUpdateQuery.setOrderBy("id des");
        appUpdateQuery.setSimplePage(new SimplePage(0,1));//获取最新一条数据
        List<AppUpdate> appUpdateList = appUpdateMapper.selectList(appUpdateQuery);
        if(!appUpdateList.isEmpty()){
            //判断版本号是否合规
            AppUpdate latest = appUpdateList.get(0);
            //字符串转为Long类型比较大小
            long dbVersion = Long.parseLong(latest.getVersion().replace(".", ""));//转换为Long类型同时去掉.变为纯数字
            long newVersion = Long.parseLong(appUpdate.getVersion().replace(".", ""));
            //新增版本号必须大于数据库中最新版本号,判断新增：新增时id先为null
            if(appUpdate.getId()==null && newVersion <= dbVersion){
                throw new BusinessException("当前版本必须大于历史最大版本");
            }
            //修改旧版的版本号---当前修改的版本号必须小于数据库中最新版本号
            if(appUpdate.getId()!=null  && !appUpdate.getId().equals(latest.getId()) && newVersion >= dbVersion ){
                throw new BusinessException("当前版本必须小于历史最大版本");
            }
            //检查版本号重复
            AppUpdate versionId = appUpdateMapper.selectByVersion(appUpdate.getVersion());
            if(versionId != null && appUpdate.getId()!=null && !appUpdate.getId().equals(versionId.getId())){
                throw new BusinessException("当前版本已存在");
            }
        }

        //新增
        if(appUpdate.getId()==null){
            appUpdate.setCreateTime(new Date());
            appUpdate.setStatus(AppUpdateSatusEnum.INIT.getStatus());
            appUpdateMapper.insert(appUpdate);
        }else{//修改---防止更新不必要的数据（前端传来的参数内被包含，权限分级），数据库只会更新非空字段
            appUpdate.setStatus(null);
            appUpdate.setGrayscaleUid(null);
            appUpdateMapper.updateById(appUpdate, appUpdate.getId());
        }
        //上传文件
        if(file != null){
            File folder = new File(appConfig.getProjectFolder() + Constants.APP_UPDATE_FOLDER);
            if (!folder.exists()) {
                folder.mkdirs();
            }
            String filePath = folder.getPath() + "/" + appUpdate.getId() + Constants.APP_EXE_SUFFIX;//设置版本文件保存路径
            file.transferTo(new File(filePath));//拷贝文件到指定路径
        }

    }

    /**
     * 发布更新
     * @param id---版本号
     * @param status
     * @param grayscaleUid
     */
    @Override
    public void postUpdate(Integer id, Integer status, String grayscaleUid) {
        //检查用户是否存在
        if(!StringTools.isEmpty(grayscaleUid)){
            UserInfo userInfo = userInfoService.getUserInfoByUserId(grayscaleUid);
            if(userInfo == null){
                throw new BusinessException("用户不存在");
            }
        }
        //获取发布类型
        AppUpdateSatusEnum statusEnum = AppUpdateSatusEnum.getByStatus(status);
        if (status == null) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        //发布类型为灰度发布时，需要传入灰度用户id
        if (AppUpdateSatusEnum.GRAYSCALE == statusEnum && StringTools.isEmpty(grayscaleUid)) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        //全网发布时，灰度用户id置空
        if (AppUpdateSatusEnum.GRAYSCALE != statusEnum) {
            grayscaleUid = "";
        }
        AppUpdate update = new AppUpdate();
        update.setStatus(status);
        update.setGrayscaleUid(grayscaleUid);
        appUpdateMapper.updateById(update, id);
    }

    /**
     * 获取最新版本信息
     * @param appVersion
     * @param uid
     * @return
     */
    @Override
    public AppUpdate getLatestUpdate(String appVersion, String uid) {
        return appUpdateMapper.selectLatestUpdate(appVersion, uid);
    }
}